﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MergeShapeFile
{

    class MergeShape
    {

        public static event EventHandler MergeShapeFiling;
        public static event EventHandler MergeShapeFiled;

        public static void ReadHead(String path, out byte[] buf)
        {
            byte[] head = new byte[100];
            FileStream FStream = new FileStream(path, FileMode.Open);
            FStream.Seek(0, SeekOrigin.Begin);
            FStream.Read(head, 0, 100);
            FStream.Close();
            buf = head;
        }

        public static void ReadBody(String path, out byte[] buf, out int len)
        {

            FileStream FStream = new FileStream(path, FileMode.Open);
            len = (int)FStream.Length - 100;
            byte[] body = new byte[len];


            FStream.Seek(100, SeekOrigin.Begin);
            FStream.Read(body, 0, len);
            FStream.Close();

            buf = body;

        }

        public static byte[] OnChangeByteOrder(byte[] input)
        {
            byte[] temp = new byte[4];
            temp[0] = input[3];
            temp[1] = input[2];
            temp[2] = input[1];
            temp[3] = input[0];
            return temp;
        }

        public static byte[] Min(byte[][] buf)
        {
            byte[] temp;
            temp = buf[0];

            double t = BitConverter.ToDouble(temp, 0);
            for (int i = 0; i < buf.Length; i++)
            {
                if (BitConverter.ToDouble(buf[i], 0) < t)
                {
                    t = BitConverter.ToDouble(buf[i], 0);
                    temp = buf[i];

                }
            }
            return temp;
        }

        public static byte[] Max(byte[][] buf)
        {
            byte[] temp;
            temp = buf[0];
            double t = BitConverter.ToDouble(temp, 0);
            for (int i = 0; i < buf.Length; i++)
            {
                if (BitConverter.ToDouble(buf[i], 0) > t)
                {
                    t = BitConverter.ToDouble(buf[i], 0);
                    temp = buf[i];
                }
            }
            return temp;
        }

        public void mergeShp(String[] names, String desc)
        {
            FileStream WriteStream;

            try
            {
                WriteStream = new FileStream(desc, FileMode.Append);
            }
            catch
            {
                return;
            }
            //读入头文件
            int fileLength = names.Length;

            byte[][] bufHead = new byte[fileLength][];
            int sum = 0;

            byte[][] temp = new byte[fileLength][];
            byte[][] tempMinX = new byte[fileLength][];
            byte[][] tempMaxX = new byte[fileLength][];
            byte[][] tempMaxY = new byte[fileLength][];
            byte[][] tempMinY = new byte[fileLength][];
            for (int i = 0; i < fileLength; i++)
            {

                ReadHead(names[i], out bufHead[i]);
                //求文件的长度
                temp[i] = new byte[] { bufHead[i][24], bufHead[i][25], bufHead[i][26], bufHead[i][27] };
                temp[i] = OnChangeByteOrder(temp[i]);
                sum += BitConverter.ToInt32(temp[i], 0) - 50;

                //空间数据所占空间范围的 X 方向最小值
                tempMinX[i] = new byte[] { bufHead[i][36], bufHead[i][37], bufHead[i][38], bufHead[i][39], bufHead[i][40], bufHead[i][41], bufHead[i][42], bufHead[i][43] };

                //空间数据所占空间范围的 Y 方向最小值
                tempMinY[i] = new byte[] { bufHead[i][44], bufHead[i][45], bufHead[i][46], bufHead[i][47], bufHead[i][48], bufHead[i][49], bufHead[i][50], bufHead[i][51] };

                //空间数据所占空间范围的 X 方向最大值
                tempMaxX[i] = new byte[] { bufHead[i][52], bufHead[i][53], bufHead[i][54], bufHead[i][55], bufHead[i][56], bufHead[i][57], bufHead[i][58], bufHead[i][59] };

                //空间数据所占空间范围的 Y 方向最大值
                tempMaxY[i] = new byte[] { bufHead[i][60], bufHead[i][61], bufHead[i][62], bufHead[i][63], bufHead[i][64], bufHead[i][65], bufHead[i][66], bufHead[i][67] };
            }

            byte[] end = OnChangeByteOrder(BitConverter.GetBytes(sum + 50));
            for (int i = 24; i <= 27; i++)
            {
                bufHead[0][i] = end[i - 24];
            }
            //空间数据所占空间范围的 X 方向最小值
            byte[] minX = Min(tempMinX);


            for (int i = 0; i < 8; i++)
            {
                bufHead[0][36 + i] = minX[i];
            }

            //空间数据所占空间范围的 Y 方向最小值

            byte[] minY = Min(tempMinY);
            for (int i = 0; i < 8; i++)
            {
                //bufHead[0][44 + i] = maxX[i];
                bufHead[0][44 + i] = minY[i];
            }

            //空间数据所占空间范围的 X 方向最大值
            byte[] maxX = Max(tempMaxX);
            for (int i = 0; i < 8; i++)
            {
                bufHead[0][52 + i] = maxX[i];
            }

            //空间数据所占空间范围的 Y 方向最大值
            byte[] maxY = Max(tempMaxY);
            for (int i = 0; i < 8; i++)
            {
                bufHead[0][60 + i] = maxY[i];
            }

            WriteStream.Write(bufHead[0], 0, 100);


            //读取实体
            int[] len = new int[fileLength];
            byte[][] bufBody = new byte[fileLength][];
            byte[] flagByte;
            byte[] ContentByte;
            int lastFlag = 0;

            for (int i = 0; i < fileLength; i++)
            {
                ReadBody(names[i], out bufBody[i], out len[i]);//读取i记录部分
                if (i < fileLength - 1)
                {
                    MergeShapeFiling(this, new EventArgs());
                }
                else
                {
                    MergeShapeFiled(this, new EventArgs());
                }
                int next = 0;//初始化为0；

                while (next != -1)
                {

                    flagByte = new byte[] { bufBody[i][next], bufBody[i][next + 1], bufBody[i][next + 2], bufBody[i][next + 3] }; //求下一个标记
                    ContentByte = new byte[] { bufBody[i][next + 4], bufBody[i][next + 5], bufBody[i][next + 6], bufBody[i][next + 7] }; //内容大小

                    flagByte = OnChangeByteOrder(flagByte);
                    ContentByte = OnChangeByteOrder(ContentByte);

                    int flag = BitConverter.ToInt32(flagByte, 0);//标记

                    int content = BitConverter.ToInt32(ContentByte, 0);//内容的大小

                    next += 8 + content * 2; //求出下一个标记

                    if (next == len[i])//等长度就退出
                    {
                        next = -1;
                        if (i == 0)
                        {
                            lastFlag = flag + 1;//下一个标记。
                        }
                        break;

                    }

                    if (i != 0)//更换标号
                    {
                        byte[] flags = BitConverter.GetBytes(lastFlag);
                        for (int a = 0; a < 4; a++)
                        {
                            bufBody[i][next + a] = flags[3 - a];
                        }
                        lastFlag++;
                    }

                }

                WriteStream.Write(bufBody[i], 0, len[i]);
            }
            WriteStream.Close();
        }
    }
}
